package cn.ant.Client;

import cn.ant.utils.ChannelUtil;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 消费者（消费任务）
 *
 * @author Anhui AntLaddie <a href="https://juejin.cn/user/4092805620185316">(掘金蚂蚁小哥)</a>
 * @version 1.0
 **/
public class Consumer {

    // 通过日志管理器获取Logger对象
    static Logger logger = LogManager.getLogger(Consumer.class);
    // 简单队列名称
    public static final String QUEUE_NAME = "helloWorldQueue";

    public static void main(String[] args) throws IOException {
        // 通过工具类获取一个信道
        Channel channel = ChannelUtil.getChannel();
        logger.info("消费者开始监听队列消息....");

        // 推送的消息如何进行消费的接口回调
        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String consumerTag, Delivery message) {
                logger.info("获取队列信息：{}",
                        new String(message.getBody(), StandardCharsets.UTF_8));
            }
        };

        // 取消消费的一个回调接口 如在消费的时候队列被删除掉了
        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String consumerTag) {
                logger.info("监听的队列出现异常；可能队列被删除！{}", consumerTag);
            }
        };

        //消费者消费消息
        //参数一：要消费的队列的名称，消费者将从这个队列中接收消息。
        //      说明：队列必须已经存在，在调用basicConsume方法之前，生产者已经向该队列发送了消息。
        //参数二：指示消费者在接收到消息后是否自动发送应答
        //      true = 自动应答，消费者在接收到消息后，RabbitMQ 会自动将该消息标记为已处理。
        //          这意味着即使消费者在处理消息时发生错误，消息也不会被重新投递。
        //      false = 手动应答，消费者需要在处理完消息后显式地发送应答（acknowledgment）。
        //          如果消费者在处理消息时发生错误且未发送应答，RabbitMQ 会将该消息重新投递给其他消费者。
        //参数三：这是一个实现了DeliverCallback接口的回调对象，用于处理接收到的消息。
        //      说明：消费者从队列中接收到消息时，RabbitMQ会调用这个回调方法，可以在这里写处理消息的逻辑。
        //参数四：这是一个实现了CancelCallback接口的回调对象，用于处理消费者取消消费的情况。
        //      说明：当消费者被取消（如，队列被删除，或者消费者主动取消）时，
        //      RabbitMQ会调用这个回调方法。您可以在这里编写处理取消的逻辑。
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}

